package com.fhyc.util;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 数据库查询 转换 对外接口展示类
 *
 * @author 夏亚南
 * @date 2024/01/16
 */
@Slf4j
public class BeanConvertUtil extends BeanUtils {


    /**
     * 单个类转换
     *
     * @param sourceObj
     * @param targetClass
     * @param <T>
     * @return
     */
    public static <T> T conver(Object sourceObj, Class<T> targetClass) {
        if (sourceObj == null || targetClass == null) {
            return null;
        }
        T targetObj = null;
        try {
            targetObj = targetClass.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            log.error("sourceObj:{},targetClass:{}", sourceObj, targetClass, e);
            return null;
        }
        BeanUtils.copyProperties(sourceObj, targetObj);
//        convertLocalDateToLocalDateTime(sourceObj, targetObj);
        return targetObj;
    }

    private static void convertLocalDateToLocalDateTime(Object sourceObj, Object targetObj) {
        Field[] fields = targetObj.getClass().getDeclaredFields();
        for (Field targetField : fields) {
            if (targetField.getType().equals(LocalDateTime.class)) {
                try {
                    String targetFieldName = targetField.getName();
                    String sourceFieldName = targetFieldName.replace("Time", "Date");
                    Field sourceField = sourceObj.getClass().getDeclaredField(sourceFieldName);
                    sourceField.setAccessible(true);
                    Object value = sourceField.get(sourceObj);
                    if (value instanceof LocalDate) {
                        LocalDate localDate = (LocalDate) value;
                        LocalDateTime localDateTime = localDate.atStartOfDay();
                        targetField.setAccessible(true);
                        targetField.set(targetObj, localDateTime);
                    }
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    log.warn("Failed to convert field: {} in sourceObj: {}", targetField.getName(), sourceObj, e);
                }
            }
        }
    }

    /**
     * List之间转换
     *
     * @param sourceList
     * @param targetClass
     * @param <T>
     * @return
     */
    public static <T> List<T> converList(List<?> sourceList, Class<T> targetClass) {
        if (CollectionUtils.isEmpty(sourceList) || targetClass == null) {
            return Collections.emptyList();
        }
        return sourceList.stream().map(sourceObj -> conver(sourceObj, targetClass)).collect(Collectors.toList());
    }

}

